use crate::conf_parse::{Ast, Expression};
use once_cell::sync::OnceCell;
use crate::{and, or, rep, lit, dot, sub_rule};
use std::sync::Arc;
use std::collections::VecDeque;
use crate::physical_plan::PhysicalPlanExpr::ConfValue;

static FUNC_RULE: OnceCell<Expression> = OnceCell::new();

pub fn logical_plan_rule_func_ref()->&'static Expression{
    /*
    func_name(abc,[a,b,c],{a,b,c})
    */

    let fr = FUNC_RULE.get_or_init(||{
        let func_arg_key = and!(lit!("["),rep!(dot!(),,,lit!("]")),lit!("]"));
        let func_arg_value = rep!(dot!(),,,or!(lit!(","),lit!(")")));
        let func_arg_enum = or!(sub_rule!("func_arg_key",func_arg_key),sub_rule!("func_arg_value",func_arg_value));
        let func_arg = and!(rep!(and!(sub_rule!("func_arg_enum",func_arg_enum),lit!(",")),,,),sub_rule!("func_arg_enum", func_arg_enum));
        let func_name = rep!(dot!(), 1, ,lit!("("));
        let func = and!(sub_rule!("func_name",func_name),lit!("("),sub_rule!("func_arg",func_arg),lit!(")"));

        func
    });

    return fr;
}


/*
有两种错误：
1.配置错误：一般是指配置参数导致的错误，filter函数功能完全无法正常运行。这种算配置错误，程序不允许正常启动。
2.运行时错误：配置参数是对的，合法的，但是可能会因为不同事件字段值或者类型导致当次无法运行成功。
    这种算配置在当前事件数据中无法生效，生成运行时告警日志，这种日志放到事件数据的changelog里面去。
*/
#[derive(Debug)]
pub enum ErrResult{
    ConfErr(VecDeque<String>),
    RunErr(VecDeque<String>),
}
impl ErrResult{
    pub fn new_conf_err(err: String)->ErrResult{
        let mut tmp = ErrResult::ConfErr(VecDeque::new());
        tmp.append_err(err);
        return tmp;
    }
    pub fn new_run_err(err: String)->ErrResult{
        let mut tmp = ErrResult::RunErr(VecDeque::new());
        tmp.append_err(err);
        return tmp;
    }
    pub fn append_err(&mut self, err: String){
        match self{
            ErrResult::ConfErr(e) => {
                e.push_front(err);
            },
            ErrResult::RunErr(e) => {
                e.push_front(err);
            },
        }
    }
    pub fn err_out(self)->VecDeque<String>{
        match self{
            ErrResult::ConfErr(e) => {e},
            ErrResult::RunErr(e) => {e},
        }
    }
}

pub fn new_func_err_result(err_desc: String)->VecDeque<String>{
    let mut err_list = VecDeque::new();
    err_list.push_back(err_desc);
    return err_list;
}



